#!/usr/bin/python

import os
import random
import codecs
import platform
import shutil
import getopt
import sys

protoPackage = "protoMsg"

class Msg:
	name = ""
	fileType  = 0
	id = 0	
	def getName(self):
		pre = ""
		if self.fileType == 1:
			pre =  protoPackage + "."        
		return pre + self.name
	
	
def genMessageCmd(src_path, go_path, json_path, lua_path, cpp_path, csharp_path):	
	maps = []
	route = {}
	out = open("out.go",'w')
	out.write("package gcommon\n")
	out.write("import \"server/" + protoPackage + "\"\n")
	out.write("import \"server/zeus/msgdef\"\n")
	
	print("src_path:" + src_path + "  to_path:" + go_path)
	for filename in os.listdir(src_path):
		#print(filename)
		startid=0
		if not os.path.isdir(filename):
			fileType = 0
			if filename.endswith(".proto"):
				fileType = 1
			if filename.endswith(".binmsg"):
				fileType = 2
			if filename == "route":
				fileType = 3
			if fileType == 0:
				continue
			
			messageType = 1
			if filename.startswith("server"):
				messageType = 0
			#print("XXXXXXXXX")
			fh = open(os.path.join(src_path , filename), encoding = 'utf-8',mode = 'r')
			print("filename " + filename)
			propmaps=[]
			for line in fh:
				line = line.replace(' ','').replace('{','').replace("\n","").replace("\t","")
				if line == "":
					continue
				if fileType == 3:
					t = line[:-1].split("=")
					if len(t) == 2:
						route[t[0]] = t[1]
				if fileType == 2 or fileType == 1:
					#print("XXX" + filename)
					if line.startswith('//StartId='):
						startid = int(line[10:])
					if line.startswith('message'):
						m =  Msg()
						m.name = line[7:]
						m.fileType = fileType
						m.id = 101
						if messageType == 1:
							m.id = startid
						propmaps.append(m)
			if startid == 0 and fileType != 3:
				print("filename " + filename + " startid not set ,error !")
			#print(propmaps)
			maps.append(propmaps)
					
	out.write("var ProtoMap = map[uint16]msgdef.IMsg{\n")	
	print(maps)
	for value1 in maps:
		k = 1
		for value in value1:
			if value.name == "ProtoSync":
				out.write("10: new("+value.getName()+"),\n")
			else:
				id = str(value.id + k)
				#if route.has_key(value.name):
				if value.name in route:
					id = route[value.name] + id
				print(value.getName().capitalize())
				out.write(id+": new("+value.getName().capitalize()+"),\n")
				value.id = int(id)
			k = k + 1
	out.write("}\n")	
	
	out.close()
	os.system("gofmt -l -w out.go")
	if len(go_path) > 0:
		copyFile("out.go", "protoMap.go", go_path)
	os.remove("out.go")
	
	binProtoFile = open("proto.json",'w')
	binProtoFile.write(protoMapBinary(maps))
	binProtoFile.close()
	copyFile("proto.json", "proto.json", json_path)	
	os.remove("proto.json")

	binProtoFile = open("prototype.h",'w')
	binProtoFile.write(protoMapToEnum(maps))
	binProtoFile.close()
	copyFile("prototype.h", "prototype.h", cpp_path)	
	os.remove("prototype.h")

	luaProtoFile = open("networkmsgid.lua",'w')
	luaProtoFile.write(protoMapToLua(maps))
	luaProtoFile.close()
	copyFile("networkmsgid.lua", "networkmsgid.lua", lua_path)	
	os.remove("networkmsgid.lua")

	CSharpProtoFile = open("ProtoMap.cs",'w')
	CSharpProtoFile.write(protoMapToCSharp(maps))
	CSharpProtoFile.close()
	copyFile("ProtoMap.cs", "ProtoMap.cs", csharp_path)	
	os.remove("ProtoMap.cs")
	
def copyFile(srcFile, dstName, *toPath):
	dstPath = os.path.join(*toPath)
	if not os.path.exists(dstPath):
		os.makedirs(dstPath)
	shutil.copyfile(srcFile, os.path.join(dstPath, dstName))
	

def protoMapBinary(maps):
	data = "{"
	for value1 in maps:
		for value in value1:
			id = str(value.id)
			if value.name == "ProtoSync":
				id = "10"
			data += "\"" + id + "\":" + "\"" + value.name + "\","
	data = data[:-1]
	data += "}"
	return data
	
	

def protoMapToEnum(maps):
	data = "\n"
	data += "#pragma once\n\n"
	for value1 in maps:
		for value in value1:
			id = str(value.id)
			if value.name == "ProtoSync":
				id = "10"
			data += "const uint16 " + "PROTOID_" + value.name + " = " + id + ";\n"
	data = data[:-1]
	return data
	
def protoMapToCSharp(maps):
	data = "using System.Collections.Generic;" + "\n"
	data += "using Google.Protobuf;\n" 
	data += "using ProtoMsg;\n" + "\n" 
	data += "public class ProtoMap\n"
	data += "{" + "\n"
	data += "    public Dictionary<int, IMessage> ProtoMapDic = new Dictionary<int, IMessage>();" + "\n" + "\n"
	data += "    public void Init()" + "\n"
	data += "    {" + "\n"
	for value1 in maps:
		k = 1
		for value in value1:
			if value.name == "ProtoSync":
				out.write("10: new("+value.getName()+"),\n")
			else:
				id = str(value.id)
				#if route.has_key(value.name):
				#if value.name in route:
					#id = route[value.name] + id
				data = data + "        ProtoMapDic.Add(" + id + ", new " + value.getName()[9:] + "());\n"
				value.id = int(id)
			k = k + 1    
	data = data + "    }" + "\n"
	data = data + "}" + "\n"  
	return data
	
def protoMapToLua(maps):
	data = "NetworkMsgID = \n\t{\n"
	for value1 in maps:
		for value in value1:
			id = str(value.id)
			if value.name == "ProtoSync":
				id = "10"
			data += "\t\t" + "PROTOID_" + value.name.upper() + " = " + id + ";\n"
	#data = data[:-1]
	data += "\t};\n\n"
	
	data += "NetworkMsgMap = \n\t{\n"
	for value1 in maps:
		for value in value1:
			id = str(value.id)
			if value.name == "ProtoSync":
				id = "10"
			data += "\t\t[" + id + "] = 'protoMsg." + value.name +"';\n"
	#data = data[:-1]
	data += "\t};"
	return data
	
if __name__ == '__main__':
	realPath = os.path.dirname(os.path.realpath(__file__))
	src_path = os.path.join(realPath ,"..\protoFile")
	outBasePath = os.path.join(realPath ,"..\..\..\..")
	go_path = os.path.join(realPath, "mapproto", "mapproto")
	json_path = os.path.join(outBasePath, "server", "res", "config")
	lua_path = os.path.join(outBasePath, "newtools", "lua")
	cpp_path = os.path.join(outBasePath, "newtools", "cpp")
	csharp_path = os.path.join(realPath, "csproto", "")
	
	if len(sys.argv) > 2:
		cpp_path = sys.argv[1]
		print("cpp_path", cpp_path)
		src_path = sys.argv[2]
		print("src_path", src_path)
		if len(sys.argv) > 3:
			go_path = sys.argv[3]
			print("go_path", go_path)
			pass
			if len(sys.argv) > 4:
				csharp_path = sys.argv[4]
				print("csharp_path", csharp_path)
				pass				
		pass
	#print("####"+csharp_path)
	genMessageCmd(src_path, go_path, json_path, lua_path, cpp_path, csharp_path)
